package com.etlmaster.jdbc;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.Calendar;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.sql.DataSource;

import org.springframework.jdbc.datasource.DataSourceUtils;

import com.etlmaster.core.BeanFactory;
import com.etlmaster.core.Configuration;
import com.etlmaster.core.DataSourceHolder;
import com.etlmaster.crypto.DesCipher;
import com.etlmaster.executor.utils.LogWriter;

/**
 * @author Larry
 * @copyright Larry@etlMaster
 * @since 2017-09-10
 */
//由于dataSource不同所以这里不能用@Compnonet
public class JdbcTemplate extends org.springframework.jdbc.core.JdbcTemplate {
	
	public static String defaultDatasourceName = "dataSource";
	public static boolean DEFAULT_USE_CACHE=false;
	
	

	public JdbcTemplate(){
		this(defaultDatasourceName);
	}

	public JdbcTemplate(DataSource dataSource){
		super(dataSource);
		
	}

	public JdbcTemplate(String defaultDatasourceName) {
		this(getDataSource(defaultDatasourceName));
	}

	/**
	 * 通过dataSourceName得到java.sql.DataSource的实例
	 * @param dataSource
	 * @return
	 */
	public static DataSource getDataSource(String dataSource){
		if(dataSource==null|| dataSource.length()==0 || "undefined".equalsIgnoreCase(dataSource)){
			dataSource=defaultDatasourceName;
		}
		DataSource ds = null;
		try{
			ds = (DataSource)BeanFactory.getBean(dataSource);
		}catch(Exception e){
			LogWriter.addLog("ERROR","未获取数据源{}",dataSource);
			LogWriter.addLog("ERROR",e.getMessage());
		}
		if(ds==null && !defaultDatasourceName.equalsIgnoreCase(dataSource)){
			return null;
		}
		return ds;
	}
	
	/**
	 * 通过dataSourceName得到java.sql.DataSource的实例
	 * @param dataSource
	 * @return
	 */
	public static DataSource getDataSource(String dataSource,String username,String password){
		if(dataSource==null|| dataSource.length()==0 || "undefined".equalsIgnoreCase(dataSource)){
			dataSource=defaultDatasourceName;
		}
		if(username==null|| username.length()==0 || "undefined".equalsIgnoreCase(username)){
			return getDataSource(dataSource);
		}else{
			try{
				password=password==null|| password.length()==0 || "undefined".equalsIgnoreCase(password)?getPassword(dataSource,username):password;
			}catch(Exception e){
				e.printStackTrace();
			}
			LogWriter.addLog("INFO","get ds by {}",dataSource);
			return DataSourceHolder.getInstance().getDataSource(dataSource, username, password);
		}
	}
	
	private static String getPassword(String dataSource,String username){
			String tableName=Configuration.getInstance().getProperty("com.asiainfo.dacp.core.DataSourceHolder.transDbTableName");
			JdbcTemplate jd=new JdbcTemplate(defaultDatasourceName);
			Map<String,Object> dbUserInfo=jd.queryForMap("select password from "+tableName+" where dbname=? and username=? group by dbname,username",new Object[]{dataSource, username});
			return (String) DesCipher.decrypt(dbUserInfo.get("password").toString());
	}
	
	/**
	 * 得到数据库的类型 全部小写的 db2 oracle mysql
	 * @return
	 */
	public String getDatabaseType(){
		return getDatabaseType(getDataSource());
	}
	
	private String getDatabaseType(DataSource dataSource){
		String driverName = "";
		Connection con = DataSourceUtils.getConnection(dataSource);
		try {
			DatabaseMetaData dbmd = con.getMetaData();
			driverName = dbmd.getDriverName();
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
			DataSourceUtils.releaseConnection(con, dataSource);
		}
		String result="";
		Pattern pattern = Pattern.compile(".*(db2|oracle|mysql|sql server|hive|teradata|gbase).*");
		Matcher m = pattern.matcher(driverName.toLowerCase());
		if(m.matches()){
			result = m.group(1);
		}else{
			result = driverName;
		}
		return result.replace(" ", "");
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		System.out.println(Calendar.getInstance().getTime());
	}

}
